Nolan Petrakis had his best year yet at Cutwater Signs, the commercial sign shop he runs out of a leased bay on the north side of Milwaukee. Revenue crossed $1.4 million for the first time. The fabrication floor ran six days a week from March through November, and the install crew was booked so far out that he turned down three jobs in September.
Then his accountant delivered the year-end P&L. Net income came in at $84,000. A 6 percent net margin on a year that nearly broke his team.
Nolan assumed the hospital wayfinding contract carried the year. It was the largest single job in the shop's history, $310,000 in signage across four buildings, and it had felt like the win that changed the business.
When he finally tracked cost by project, the hospital job had lost $14,200. The work that paid for his year was a stack of unglamorous monument sign replacements for car dealerships, $9,000 apiece, twenty-two of them, running at a 41 percent gross margin.
He had spent the year chasing the wrong kind of work because his financial statements gave him no way to tell the difference.
What a P&L can and cannot answer
Your income statement aggregates. It tells you that the company spent $412,000 on direct labor across the year. It cannot tell you that $71,000 of that went into one contract that only billed $310,000 in the first place.
Job costing solves that by treating each project as its own cost object. Every dollar of material, labor, subcontract, and overhead gets assigned to a specific job number, and the accumulated costs live on a job cost sheet that stays open until the project closes.
The distinction is important. Process costing averages cost across large volumes of identical units, which suits a bottling plant. Job costing tracks cost for distinct, custom orders, which suits anyone doing project work: contractors, fabricators, agencies, custom manufacturers, and professional services firms billing by engagement.
The four buckets every job sheet needs
Let’s talk about each one.
- Direct materials cover anything traceable to the job. On a sign build that means aluminum, acrylic, LED modules, vinyl, and paint. Requisition it against the job number the moment it leaves the rack.
- Direct labor is the one owners consistently understate because they use the hourly wage instead of the fully loaded rate. A fabricator earning $27 an hour costs considerably more than $27.
Loaded labor rate = (Base wages + employer payroll taxes + benefits + workers' compensation premium) ÷ Productive hours
Employer FICA runs 7.65 percent, and sign shop workers' comp classifications frequently price above 8 percent of payroll. Add health coverage and paid time off, and Nolan's $27 fabricator costs $37.40 per productive hour. Productive hours matter here too. A worker paid for 2,080 hours is rarely billable for more than about 1,700 after holidays, training, and shop cleanup.
- Subcontractors and outside services cover permits, crane rental, electrical hookup, and anything billed by a third party against that specific project.
- Applied overhead is the bucket most small shops skip entirely. Rent, utilities, software, insurance, the estimator's salary, and truck payments do not vanish because they are hard to trace. They get recovered through jobs or they get absorbed by your net income.
Predetermined overhead rate = Estimated annual overhead ÷ Estimated annual direct labor hours
Cutwater's overhead ran $268,000 against 6,700 estimated direct labor hours, which gives an application rate of $40 per direct labor hour. Every hour charged to a job also carries $40 of shop cost.
What Nolan's two jobs actually looked like
| Cost element |
Hospital wayfinding |
Dealership monument |
| Contract revenue |
$310,000 |
$9,000 |
| Direct materials |
$118,400 |
$2,150 |
| Direct labor (loaded) |
$71,000 |
$1,420 |
| Subcontractors and permits |
$46,300 |
$610 |
| Applied overhead |
$88,500 |
$1,520 |
| Total job cost |
$324,200 |
$5,700 |
| Gross profit |
($14,200) |
$3,300 |
| Gross margin |
(4.6%) |
36.7% |
Job gross margin = (Job revenue − Total job cost) ÷ Job revenue
The hospital contract consumed 1,775 direct labor hours against an estimate of 1,150. Change orders on mounting details went unbilled because nobody documented them at the time. Permit costs in three municipalities came in higher than quoted. Each of those failures was survivable on its own, and together they turned the shop's flagship project into a loss.
Deciding what counts as a job
Before any of this works, you have to define the unit. For a fabricator it is a purchase order. For an agency it is a client engagement or a retainer month. For a plumber it is a work order. Pick the smallest unit of work that carries its own price and its own scope, because anything larger hides the losses inside an average.
Most accounting platforms already support this. QuickBooks calls it "Projects," Xero calls it "Tracking Categories," and both let you tag every bill, timesheet entry, and invoice to a code. The setup takes an afternoon. The discipline of tagging costs on the day they occur is the part that fails, and it fails quietly because a receipt dropped into a general supplies account still balances the books. It just stops telling you anything.
Three leaks show up in almost every shop that starts tracking. Materials bought for one job get pulled onto another and never get reclassified. Crew time spent driving between sites or reworking a mistake gets logged as general shop hours because nobody wants to admit which job it belonged to. And unbilled change orders get absorbed as a favor to the client, then forgotten by the time the job closes.
Estimate versus actual is where the money is
A job sheet you only read after the fact is a history lesson. The value comes from variance analysis while work is still open.
| Line item |
Estimated |
Actual |
Variance |
| Direct labor hours |
1,150 |
1,775 |
625 over |
| Materials |
$109,000 |
$118,400 |
$9,400 over |
| Subcontractors |
$38,000 |
$46,300 |
$8,300 over |
Nolan now runs a work-in-process report every Friday showing costs accumulated against budget on every open job. When labor hours cross 60 percent of estimate before the project is 60 percent complete, he knows in week three instead of month seven.
Turning the data into pricing
After ten closed jobs, patterns surface. Cutwater discovered that multi-building institutional work carried roughly triple the estimating and coordination hours of retail work, none of which was priced into the bid. Dealership monuments repeated the same fabrication steps with almost no design time.
So Nolan added a coordination factor to institutional bids, raised his overhead application rate to reflect actual shop cost, and started writing change orders before the work happened instead of eating them.
The dealership work was never the exciting part of the business. It was the part that paid the bills, and the only reason he knows that is that he finally started counting one job at a time.